package il.ac.braude.sona.gui.infogui;

import il.ac.braude.sona.constants.ButtonPermission;
import il.ac.braude.sona.constants.Mssg;
import il.ac.braude.sona.constants.P;
import il.ac.braude.sona.constants.Resources;
import il.ac.braude.sona.constants.TestingParamKit;
import il.ac.braude.sona.control.AppointWorkersToStagesController;
import il.ac.braude.sona.control.BoardDecisionController;
import il.ac.braude.sona.control.CloseRequestController;
import il.ac.braude.sona.control.ExecutionController;
import il.ac.braude.sona.control.ExtensionsController;
import il.ac.braude.sona.control.FreezingReqController;
import il.ac.braude.sona.control.LoginController;
import il.ac.braude.sona.control.SurveyReportController;
import il.ac.braude.sona.control.TesterController;
import il.ac.braude.sona.control.TimeLineController;
import il.ac.braude.sona.entities.ChangeRequest;
import il.ac.braude.sona.entities.FileTransfer;
import il.ac.braude.sona.gui.ButtonPanel;
import il.ac.braude.sona.gui.SONAFrame;
import il.ac.braude.sona.ocsf.client.Client;
import il.ac.braude.sona.ocsf.client.ServerResponseListener;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

import com.ofekron.genericlist.List;
import com.ofekron.genericlist.ListController;
import com.ofekron.genericlist.standart.ListStandartModel;
/**
 * Info frame to show all info for a specific ChangeRequest instance
 * @author  Ofek Ron
 * @author Avihay Avitan
 * @author Nitzan Inbar
 * @author Sasha Rozenthal
 * Laboratory in Software Engineering,Ort Braude College.</p>
 *
 */
public class RequsetInfoFrame extends InfoFrame {
	private ButtonPanel myButtonPanel = new ButtonPanel();
	private AppointWorkersToStagesController appointWorkers = new AppointWorkersToStagesController();
	private TimeLineController timeLine = new TimeLineController();
	private SurveyReportController survController= new SurveyReportController(); 
	private HashSet<String> premissions;
	private ExtensionsController extcontroller= new ExtensionsController();
	private BoardDecisionController boardController=new BoardDecisionController();
	private ExecutionController executionController=new ExecutionController();
	private TestingParamKit TestKit=TestingParamKit.getTestingKit();
    private TesterController testControll= new TesterController();
    private CloseRequestController closeReqControll=new CloseRequestController();
    private FreezingReqController freezControll= new FreezingReqController();
	/**
	 * showing all info in the change request req
	 * @param req
	 */
	public RequsetInfoFrame(ChangeRequest req) {
		super(Resources.Strings.RequestInfoTitle);
		setInfoPanel(prepareInfoPanel(req));
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		pack();
		setLocation(dim.width/2 - getWidth()/2, dim.height/2 - getHeight()/2);
		setVisible(true);
		showFrame();

	}
	public RequsetInfoFrame(HashMap<String,String> values) {
		super(Resources.Strings.RequestInfoTitle);
		InfoPanel infoPanel = new InfoPanel();
		infoPanel.addTitleWithUnderline("View Request Information");
		addInfoRows(infoPanel,values);
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		pack();
		setLocation(dim.width/2 - getWidth()/2, dim.height/2 - getHeight()/2);
		
		add(infoPanel);
		setVisible(true);
		showFrame();
	}

	private void addInfoRows(InfoPanel infoPanel, HashMap<String, String> values) {
		Set<Entry<String, String>> reportData = values.entrySet();
		Iterator<Entry<String, String>> mapitarator = reportData.iterator();
         
		while (mapitarator.hasNext())
		{
			Entry<String, String> map = mapitarator.next();
			infoPanel.addInfoRow(map.getKey(),map.getValue());
		}
		  //  JTextArea ta;
		//	ta=new JTextArea(req.getValue(ChangeRequest.all_fields[i]));
		//	ta.setEditable(false);
		//	ta.setOpaque(false);
		//	infoPanel.addInfoRow(ChangeRequest.all_fields[i] ,ta);
		
	}
	private InfoPanel prepareInfoPanel(ChangeRequest req) {
		InfoPanel infoPanel = new InfoPanel();
		infoPanel.addTitleWithUnderline("View Request Information");
		addInfoRows(infoPanel,req);
		infoPanel.add(myButtonPanel = new ButtonPanel());
		showButtonsAccordingToPermissions(req);
		handleListOfFiles(infoPanel,req);
		return infoPanel;
	}
	

/**
 * sets the buttons
 * @param req
 */
	private void showButtonsAccordingToPermissions(final ChangeRequest req) {
		try {
			ArrayList<String> values=new ArrayList<String>();
			values.add(LoginController.user.getValue("tid"));
			values.add(LoginController.user.getID());
			values.add(req.getID());
			values.add(req.getValue("Status"));
			
			Mssg msg = new Mssg(P.GetButtonPermissions,values);
			Client.getInstance().sendToServer(new ServerResponseListener() {
				@SuppressWarnings("unchecked")
				@Override
				public void onServerResponse(Mssg mssg) {
					if (mssg.is(P.error)) {
						JOptionPane.showMessageDialog(null, mssg.getMessege());
						return;
						}
					if ((premissions = new  HashSet<String>((HashSet<String>)mssg.getMessege())) != null) {	
						if (premissions.contains(ButtonPermission.WriteSurveyReport)){
							addButton(ButtonPermission.WriteSurveyReport,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								survController.execCreateSurveyReport(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.ApproveTimeLine)){
							addButton(ButtonPermission.ApproveTimeLine,new ActionListener() {
								@Override
								public void actionPerformed(ActionEvent e) {
									timeLine.viewApproveTimeLineForm(req.getID(),req.getValue("Status"),RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.EstimateTimeLine)){
							addButton(ButtonPermission.EstimateTimeLine,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
									timeLine.ViewEstimateTimeLineForm(req.getID(),req.getValue("Status"),RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.AppointWorkersToReq)){
							addButton(ButtonPermission.AppointWorkersToReq,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
									appointWorkers.execViewAppointWorkers(req,RequsetInfoFrame.this);
									
								}
							});
						}
						if (premissions.contains(ButtonPermission.AppointTester)){
							addButton(ButtonPermission.AppointTester,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
									appointWorkers.execViewAppointTester(req.getID(),RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.ViewSurveyReport)){
							addButton(ButtonPermission.ViewSurveyReport,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								survController.execViewSurveyReport(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.EditSurveryReport)){
							addButton(ButtonPermission.EditSurveryReport,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								survController.execEditSurveyReport(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.MakeDecision)){
							addButton(ButtonPermission.MakeDecision,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								boardController.execMakeDecision(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.ApproveBoardDecision)){
							addButton(ButtonPermission.ApproveBoardDecision,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								boardController.execApproveDecision(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.ApproveModifications)){
							testControll.CheckForFailursReport(req,RequsetInfoFrame.this);
							addButton(ButtonPermission.ApproveModifications,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?", ButtonPermission.ApproveModifications, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	executionController.approveModifications(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						if (premissions.contains(ButtonPermission.ModificationTested)){
							addButton(ButtonPermission.ModificationTested,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?", ButtonPermission.ModificationTested, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	testControll.approveTestModificated(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						if (premissions.contains(ButtonPermission.ReportTestFailures)){
							addButton(ButtonPermission.ReportTestFailures,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
							    	testControll.execReportTestFailurs(req,RequsetInfoFrame.this);
								}
							});
						}
						if (premissions.contains(ButtonPermission.SupervisorCloseAndNotify)){
							addButton(ButtonPermission.SupervisorCloseAndNotify,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?", ButtonPermission.SupervisorCloseAndNotify, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	closeReqControll.closeAndNotifyUser(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						if (premissions.contains(ButtonPermission.UserConfirm)){
							addButton(ButtonPermission.UserConfirm,new ActionListener() {

								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?", ButtonPermission.UserConfirm, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	closeReqControll.execUserConfirmation(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						if (premissions.contains(ButtonPermission.FreezeRequest)){
							addButton(ButtonPermission.FreezeRequest,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?\nWarning: All request processes will be suspended!", ButtonPermission.FreezeRequest, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	freezControll.execFreezingRequest(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						if (premissions.contains(ButtonPermission.UnFreezeRequest)){
							addButton(ButtonPermission.UnFreezeRequest,new ActionListener() {
								
								@Override
								public void actionPerformed(ActionEvent e) {
								    int reply = JOptionPane.showConfirmDialog(RequsetInfoFrame.this, "Are you sure?", ButtonPermission.UnFreezeRequest, JOptionPane.YES_NO_OPTION);
								    if (reply == JOptionPane.YES_OPTION)
								    {
								    	freezControll.execThawingRequest(req,RequsetInfoFrame.this);
								    }
								 }


							});
						}
						TestKit.extensionPerm = false;
						if (premissions.contains(ButtonPermission.reqExtension)){
							TestKit.extensionPerm = true;
							
							addButton(ButtonPermission.reqExtension,(new ActionListener() {
								@Override
								public void actionPerformed(ActionEvent e) {
									extcontroller.execExtensionForm(req.getID(),req.getValue("Status"),req.getValue("Owner"),((JButton)e.getSource()));
								}}));
						}

					}

					RequsetInfoFrame.this.showFrame();
				}
			},msg);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}


	private void addInfoRows(InfoPanel infoPanel, ChangeRequest req) {
		for (int i=0; i < 6  ; i++)
			infoPanel.addInfoRow(ChangeRequest.all_fields[i] ,req.getValue(ChangeRequest.all_fields[i]));
		JTextArea ta;
		for (int i=6; i < ChangeRequest.all_fields.length ; i++) {
			ta=new JTextArea(req.getValue(ChangeRequest.all_fields[i]));
			ta.setEditable(false);
			ta.setOpaque(false);
			infoPanel.addInfoRow(ChangeRequest.all_fields[i] ,ta);
		}
	}

/**
 * add buttons to this info frame
 * @param title
 * @param listener
 */
	public void addButton(String title,ActionListener listener) {
		myButtonPanel.addButton(title, listener);
	}
/**
 * this method makes the list of files corresponding tot this change request instance
 * @param infoPanel
 * @param req
 */
	private void handleListOfFiles(InfoPanel infoPanel, final ChangeRequest req) {
		List<String> filesList = new List<String>(new ListStandartModel<String>(req.getFilenames()), new ListController<String>() {

			@Override
			public void executeUpdateCommand(List<String> list, String oldItem,
					String newItem) {
				// TODO Auto-generated method stub

			}

			@Override
			public void executeRemoveCommand(List<String> list, String item) {
				// TODO Auto-generated method stub

			}

			@Override
			public void executeFocusCommand(String item) {
				// TODO Auto-generated method stub

			}

			@Override
			public void executeChooseCommand(String item) {
				JFileChooser fchooser = new JFileChooser();
				fchooser.setApproveButtonText(Resources.Strings.Saveas);
				fchooser.setSelectedFile(new File(item));
				int returnVal = fchooser.showSaveDialog(RequsetInfoFrame.this);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					final File file = fchooser.getSelectedFile();
					
					final SONAFrame downloading = new SONAFrame();
					downloading.getContentPane().add(new JLabel(Resources.Strings.Downloading,SwingConstants.CENTER));
					downloading.showFrame();
					try {
						Client.getInstance().sendToServer(new ServerResponseListener() {

							@Override
							public void onServerResponse(Mssg mssg) {
								if (mssg.is(P.error))  {
									JOptionPane.showMessageDialog(RequsetInfoFrame.this, mssg.getMessege().toString());
									return;
								}

								try {
									((FileTransfer)mssg.getMessege()).writeToFile(file);
									JOptionPane.showMessageDialog(RequsetInfoFrame.this, String.format(Resources.Strings.DownloadedSuccesfuly, file.getPath()));
								} catch (IOException e) {
									e.printStackTrace();
								}
								downloading.dispose();
							}
						},new P.ViewMssg(P.ViewMssg.view_file_by_rid_and_name,req.getID(),item));
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

			}

			@Override
			public void executeAddCommand(List<String> list, String item) {
				// TODO Auto-generated method stub

			}

			@Override
			protected JPopupMenu getRightClickPopUpMenu(List<String> list,
					String selectedValue) {
				// TODO Auto-generated method stub
				return null;
			}
		});

		infoPanel.add(new JLabel("Added Files : ",SwingConstants.LEFT));
		infoPanel.add(filesList);
	}
}
